/**
 * 泛型工具
 */
interface User {
    address:string
    name:string
    age:number
}

/**
 * Partial:所有属性可选的意思,接收一个泛型
 */
type partialUser = Partial<User>
//Partial实现方式
type coustomPartial<T> = {
    [p in keyof T]?:T[p]
}

/**
 * Required:所有属性必选的意思
 */
type RequiredUser = Required<User>
//Required实现方式
type coustomRequired<T> = {
    [p in keyof T]-?:T[p]
}
/**
 * Pick:提取部分属性
 * Pick接收两个泛型(<interface,接收的属性,支持联合类型>)
 */
type PickUser = Pick<User,'age' | 'name'>
//Pick实现方式
type coustomPick<T,K extends keyof T> = {
    [P in K]-?:T[P]
}
/**
 * Exclude:排除部分属性
 *
 */
type ExcludeUser = Exclude<'a' | 'b' | 'c','c' | 'a'>
//Exclude实现方式
type coustomExclude<T,K> = T extends K ? never : T
/**
 * Omit:排除部分属性,并返回新的属性,和Pick相反
 *
 */
type OmitUser = Omit<User, 'age' | 'name'>
//实现方式:Exclude+Pick  Exclude排除不需要的属性+Pick提取剩下的属性
type coustomOmit<T,K extends keyof T> = Pick<T,Exclude<keyof T, K>>


/**
 * Record:约束对象的key和value的,所以接收两个泛型
 */
//Record实现方式
    //1.对象的key只能是string number symbol
    type ObjKey = keyof any
    type coustomRecord<K extends ObjKey,T> = {
        [P in K]:T
    }
type key = 'c' | 'x' | 'k'//一个不能少
type value = '唱歌' | '跳舞' | 'rap'//随便
let obj:Record<key, value> = {
    c:'唱歌',
    x:'唱歌',
    k:'唱歌'
}
//支持嵌套写法
let obj1:Record<key, Record<key,value>> = {
    c:{
        c:'唱歌',
        x:'唱歌',
        k:'唱歌',
    },
    x:{
        c:'唱歌',
        x:'唱歌',
        k:'唱歌',
    },
    k:{
        c:'唱歌',
        x:'唱歌',
        k:'唱歌',
    }
}
/**
 * ReturnType:获取函数类型的返回值
 */
//ReturnType的实现方式   F extends (...args:any[])条件类型   infer做结果推断的
    type coustomReturnType<F extends Function> = F extends (...args:any[]) => infer Result ? Result : never
const fn =() => [1,'1',false,'adsaf']
type arrNum = ReturnType<typeof fn>